﻿namespace NTLib.Pipe
{
    using Core.Component;
    using Descriptors;
    using Exceptions;
    using Providers;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// Define the pipe manager behavior
    /// </summary>
    public interface IPipeManager : IComponentLoader<IPipeProvider>
    {
        #region Methods

        /// <summary>
        /// Creates asynchronously the pipe in function of the target.
        /// </summary>
        /// <typeparam name="T">Type of the object that will travel through the pipe.</typeparam>
        /// <param name="type">The type.</param>
        /// <param name="target">The target description used to construct properly the pipe.</param>
        /// <returns>
        /// Pipe object used to transfert data.
        /// </returns>
        /// <exception cref="TargetNotFoundException">Raised if we couldn't reach the target.</exception>
        /// <exception cref="NTLib.Pipe.Exceptions.NoProviderRegisterException">Raised if no provider can managed the specific kind of target.</exception>
        Task<IPipeManipulatorOwner<T>> CreateAsync<T>(ITargetDescriptor target, PipeType type = PipeType.OneWay, CancellationToken token = default(CancellationToken));

        /// <summary>
        /// Gets the other side of the pipe from the pipe ID.
        /// </summary>
        /// <typeparam name="T">Type object that will travel through the pipe</typeparam>
        /// <param name="pipeId">The pipe identifier.</param>
        /// <returns>Return asynchrounously the other side of the pipe from the pipe ID</returns>
        /// <exception cref="NTLib.Pipe.Exceptions.NoProviderRegisterException">Raised if no provider have a pipe for this Guid.</exception>
        Task<IPipeManipulator<T>> GetPipeAsync<T>(Guid pipeId);

        #endregion
    }
}
